import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:fixnum/fixnum.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import '../protos/douyin.pb.dart' as douyin;

class DouyinMessageParser {
  static WebSocketChannel? _webSocket;

  // 设置 WebSocket 实例用于发送 ACK
  static void setWebSocket(WebSocketChannel webSocket) {
    _webSocket = webSocket;
  }

  // 修改：返回解析后的消息列表
  static List<douyin.Message> parseWebSocketMessage(Uint8List data) {
    try {
      
      // 解析外层 PushFrame
      final pushFrame = douyin.PushFrame.fromBuffer(data);
      
      // 处理 payload
      List<int> payloadData;
      try {
        payloadData = gzip.decode(pushFrame.payload);
      } catch (e) {
        payloadData = pushFrame.payload;
      }
      
      // 3. 解析 Response
      final response = douyin.Response.fromBuffer(Uint8List.fromList(payloadData));
      
       // 4. 如果需要 ACK，发送确认
      if (response.needAck) {
        _sendAck(pushFrame.logId, response.internalExt);
      }
      
      // 返回所有消息
      return response.messagesList;
      
    } catch (e) {
      print('解析消息错误: $e');
      return [];
    }
  }
  
    // 发送 ACK 确认
  static void _sendAck(Int64 logId, String internalExt) {
    try {
      if (_webSocket == null) {
        print('警告: 需要发送 ACK 但未设置 WebSocket 实例');
        return;
      }
      
       // 构建 ACK 消息 - 使用正确的方式创建对象
      final ackFrame = douyin.PushFrame.create()
        ..payloadType = 'ack'
        ..logId = logId
        ..payload = utf8.encode(internalExt);
      
      final ackData = ackFrame.writeToBuffer();
      _webSocket!.sink.add(ackData);
    
    } catch (e) {
      print('发送 ACK 错误: $e');
    }
  }

  // 构建心跳包
  static Uint8List buildHeartbeat() {
    try {
      final heartbeatFrame = douyin.PushFrame.create()
            ..payloadType = 'hb'
            ..logId = Int64(DateTime.now().millisecondsSinceEpoch);
          
      return heartbeatFrame.writeToBuffer();
    } catch (e) {
      print('构建心跳包错误: $e');
      return Uint8List(0);
    }
  }

  // 将 protobuf 消息转换为界面可用的格式
  static Map<String, dynamic>? convertToUIMessage(douyin.Message message) {
    try {
      switch (message.method) {
        case 'WebcastChatMessage':
          return _convertChatMessage(message);
        default:
          return null;
      }
    } catch (e) {
      print('转换消息错误: $e');
      return null;
    }
  }
  
  static Map<String, dynamic> _convertChatMessage(douyin.Message message) {
    final chatMessage = douyin.ChatMessage.fromBuffer(message.payload);
    final user = chatMessage.user;
    
    return {
      'type': 'chat',
      'user': {
        'id': user.id.toString(),
        'name': user.nickName,
        'level': user.level,
        'short_id': user.shortId.toString(),
      },
      'content': chatMessage.content,
      'timestamp': DateTime.now().millisecondsSinceEpoch,
      'rawType': message.method,
    };
  }
}